use std::thread;
use std::error::Error;
use std::net::{TcpListener, TcpStream};
use crate::json_parse::CfgInfo;
use crate::app_layer;

pub fn task_start(param: &CfgInfo) -> Result<(), Box<dyn Error>>
{
    let addr = format!("{}:{}", param.ip, param.port);
    println!("Server listening on {}", addr);
    let listener = TcpListener::bind(&addr)?;
    let mut handler = vec![];

    for stream in listener.incoming() {
        match stream {
            Ok(stream) => {
                println!("new {} connection to {}", stream.peer_addr().unwrap(), addr);
                let stream1 = stream.try_clone()?;

                handler.push(thread::spawn(move || {
                    handle_client(stream1);
                }));
            }
            Err(e) => {
                eprintln!("Error on {}: {}", addr, e);
            }
        }
    }

    for i in handler {
        i.join().unwrap();
    }

    Ok(())
}

fn handle_client(stream: TcpStream)
{
    app_layer::handle_request(stream).unwrap_or_else(|err| {
        eprintln!("app_layer error: {}", err);
    });
}